#include <stdio.h>
#include "du_websocket_client.h"




static const char *TAG = "websocket";

static TimerHandle_t shutdown_signal_timer;
static SemaphoreHandle_t shutdown_sema;
static esp_websocket_client_handle_t client;


WebSocketData received_data;

bool is_recording_file = true;
//"/spiffs/recorded_audio.pcm"
static void recording_audio(const char *file_name,char *data, int data_len)
{
    FILE *f = fopen(file_name, "wb");
    if (f == NULL)
    {
        ESP_LOGE(TAG, "Failed to open file for writing");
    }

    // Write binary data to the file
    size_t bytes_written = fwrite(data, 1, data_len, f);
    if (bytes_written != data_len)
    {
        ESP_LOGE(TAG, "Failed to write entire data to file");
        fclose(f);
    }

    // Close the file
    fclose(f);
    ESP_LOGI(TAG, "Binary data saved to file");

}


#define MAX_DATA_SIZE 1024  // 根据你的需求设置合适的数据大小
// 封装文件读取和发送函数
static size_t read_file_and_send_data(const char *file_name, esp_websocket_client_handle_t client) {
    FILE* file = fopen(file_name, "rb");
    if (file == NULL) {
        ESP_LOGE(TAG, "Failed to open file for reading");
        return 0;
    }

    char buffer[MAX_DATA_SIZE];
    size_t total_bytes_sent = 0;
    size_t bytes_read;

    while ((bytes_read = fread(buffer, 1, MAX_DATA_SIZE, file)) > 0) {
        esp_websocket_client_send_bin_partial(client, buffer, bytes_read, portMAX_DELAY);
        esp_websocket_client_send_bin(client, buffer, bytes_read, portMAX_DELAY);
        total_bytes_sent += bytes_read;
    }

    fclose(file);

    return total_bytes_sent;
}

static void shutdown_signaler(TimerHandle_t xTimer)
{
    ESP_LOGI(TAG, "No data received for %d seconds, signaling shutdown", NO_DATA_TIMEOUT_SEC);
    xSemaphoreGive(shutdown_sema);
}

static void websocket_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
    esp_websocket_event_data_t *data = (esp_websocket_event_data_t *)event_data;
    switch (event_id)
    {
    case WEBSOCKET_EVENT_CONNECTED:
        ESP_LOGI(TAG, "WEBSOCKET_EVENT_CONNECTED");
        break;
    case WEBSOCKET_EVENT_DISCONNECTED:
        ESP_LOGI(TAG, "WEBSOCKET_EVENT_DISCONNECTED");

        break;
    case WEBSOCKET_EVENT_DATA:
        ESP_LOGI(TAG, "WEBSOCKET_EVENT_DATA");

        cJSON *root = cJSON_Parse(data->data_ptr);
        cJSON *content = cJSON_GetObjectItem(root, "stt_content");
        if (content != NULL && cJSON_IsString(content))
        {
            strncpy(received_data.data.stt_content, content->valuestring, MAX_CONTENT_LENGTH - 1);
            received_data.data.stt_content[MAX_CONTENT_LENGTH - 1] = '\0'; // Ensure null-terminated
            received_data.dataType = 0;  // Indicates stt_content is valid
        }
        else
        {
            ESP_LOGE(TAG, "Failed to get 'stt_content' from JSON");
        }

        // Repeat the same for 'content' and 'tts_content'
        content = cJSON_GetObjectItem(root, "content");
        if (content != NULL && cJSON_IsString(content))
        {
            //这里的语音文件比较大 是否可以考虑保持成文件
            if (is_recording_file)
            {
                recording_audio("/spiffs/recorded_audio.pcm",content->valuestring,MAX_CONTENT_LENGTH - 1);
            }
            else
            {
            strncpy(received_data.data.chat_content, content->valuestring, MAX_CONTENT_LENGTH - 1);
            received_data.data.chat_content[MAX_CONTENT_LENGTH - 1] = '\0';
            received_data.dataType = 1;  // Indicates stt_content is valid  

            }
          
        }
        else
        {
            ESP_LOGE(TAG, "Failed to get 'content' from JSON");
        }

        content = cJSON_GetObjectItem(root, "tts_content");

        if (content != NULL && cJSON_IsString(content))
        {
            

            strncpy(received_data.data.tts_content, content->valuestring, MAX_AUDIO_LENGTH - 1);
            received_data.data.tts_content[MAX_AUDIO_LENGTH - 1] = '\0';
            received_data.dataType = 2;  // Indicates stt_content is valid           
        }
        else
        {
            ESP_LOGE(TAG, "Failed to get 'tts_content' from JSON");
        }

        cJSON_Delete(root);


        xTimerReset(shutdown_signal_timer, portMAX_DELAY);
        break;


    case WEBSOCKET_EVENT_ERROR:
        ESP_LOGI(TAG, "WEBSOCKET_EVENT_ERROR");

        break;
    }
}

void websocket_app_start_init(void)
{

    // 创建定时器和信号量
    shutdown_signal_timer = xTimerCreate("Websocket shutdown timer", NO_DATA_TIMEOUT_SEC * 1000 / portTICK_PERIOD_MS,
                                         pdFALSE, NULL, shutdown_signaler);
    shutdown_sema = xSemaphoreCreateBinary();

}


// 修改主函数来调用封装的函数
void websocket_app_start_stt(char *url, char *file_name, DataCallback callback) {
    esp_websocket_client_config_t websocket_cfg = {};
    websocket_cfg.uri = url;

    websocket_cfg.skip_cert_common_name_check = true;

    ESP_LOGI(TAG, "Connecting to %s...", websocket_cfg.uri);

    // 初始化 WebSocket 客户端
    client = esp_websocket_client_init(&websocket_cfg);
    if (client == NULL) {

        ESP_LOGE(TAG, "Failed to initialize WebSocket client");
        return;
    }

    // 注册 WebSocket 事件处理函数
    esp_websocket_register_events(client, WEBSOCKET_EVENT_ANY, websocket_event_handler, (void *)client);

    // 启动 WebSocket 客户端
    esp_websocket_client_start(client);

    // 调用封装的函数来读取文件并发送数据
    size_t total_bytes_sent = read_file_and_send_data(file_name, client);

    // 发送完成后的操作（可以根据需要进行调整）
    xTimerStart(shutdown_signal_timer, portMAX_DELAY);
    xSemaphoreTake(shutdown_sema, portMAX_DELAY);

    // 关闭 WebSocket 客户端
    esp_websocket_client_close(client, portMAX_DELAY);
    ESP_LOGI(TAG, "Websocket Stopped");

    // 销毁 WebSocket 客户端
    esp_websocket_client_destroy(client);

    callback(received_data.data.stt_content);
}


//ws://127.0.0.1:8000/v1/message/chat?app_id=5aabb6b9&api_key=2a2f1eb0de3d05c41bdc46ff73cfbe8a&api_secrt=00a34f2ddf7b566cd6ea2200d033ca7e
void websocket_app_start_chat(char * url ,char * chat_message, DataCallback callback)
{
    esp_websocket_client_config_t websocket_cfg = {};

    // 填充 WebSocket 配置
    websocket_cfg.uri = url;
    websocket_cfg.skip_cert_common_name_check = true;

    ESP_LOGI(TAG, "Connecting to %s...", websocket_cfg.uri);

    // 初始化 WebSocket 客户端
    client = esp_websocket_client_init(&websocket_cfg);
    if (client == NULL)
    {
        ESP_LOGE(TAG, "Failed to initialize WebSocket client");
        return;
    }

    // 注册 WebSocket 事件处理函数
    esp_websocket_register_events(client, WEBSOCKET_EVENT_ANY, websocket_event_handler, (void *)client);

    // 启动 WebSocket 客户端
    esp_websocket_client_start(client);

    // char *message = "写一个四句诗词 描写夏天的炎热";
    int length = strlen(chat_message); // 获取字符串实际长度，不包括结尾的空字符 '\0'
    esp_websocket_client_send_text(client, chat_message, length, portMAX_DELAY);

    // 启动定时器
    xTimerStart(shutdown_signal_timer, portMAX_DELAY);

    // 等待信号量释放，这里要确保信号量在适当的时候释放
    xSemaphoreTake(shutdown_sema, portMAX_DELAY);

    // 关闭 WebSocket 客户端
    esp_websocket_client_close(client, portMAX_DELAY);
    ESP_LOGI(TAG, "Websocket Stopped");

    // 销毁 WebSocket 客户端
    esp_websocket_client_destroy(client);
    callback(received_data.data.chat_content);
}

void websocket_app_start_tts(char * url ,char * tts_message, DataCallback callback)
{
    esp_websocket_client_config_t websocket_cfg = {};


    // 填充 WebSocket 配置
    websocket_cfg.uri = url;
    websocket_cfg.skip_cert_common_name_check = true;

    ESP_LOGI(TAG, "Connecting to %s...", websocket_cfg.uri);

    // 初始化 WebSocket 客户端
    client = esp_websocket_client_init(&websocket_cfg);
    if (client == NULL)
    {
        ESP_LOGE(TAG, "Failed to initialize WebSocket client");
        return;
    }

    // 注册 WebSocket 事件处理函数
    esp_websocket_register_events(client, WEBSOCKET_EVENT_ANY, websocket_event_handler, (void *)client);

    // 启动 WebSocket 客户端
    esp_websocket_client_start(client);

    // char *message = "写一个四句诗词 描写夏天的炎热";
    int length = strlen(tts_message); // 获取字符串实际长度，不包括结尾的空字符 '\0'
    esp_websocket_client_send_text(client, tts_message, length, portMAX_DELAY);

    // 启动定时器
    xTimerStart(shutdown_signal_timer, portMAX_DELAY);

    // 等待信号量释放，这里要确保信号量在适当的时候释放
    xSemaphoreTake(shutdown_sema, portMAX_DELAY);

    // 关闭 WebSocket 客户端
    esp_websocket_client_close(client, portMAX_DELAY);
    ESP_LOGI(TAG, "Websocket Stopped");

    // 销毁 WebSocket 客户端
    esp_websocket_client_destroy(client);
    callback(received_data.data.tts_content);
}

